{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python 入门和基础命令"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 这一节主要介绍python的一些基础和常用的方法和命令\n",
    "\n",
    "### 数值类型介绍\n",
    "\n",
    "** 常见的有整数，如10，1028，-104，和浮点数12.3，-11.2，也可以用科学记数法进行表示，比如1.2e12 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 <class 'int'>\n",
      "1028 <class 'int'>\n",
      "-104 <class 'int'>\n",
      "12.3 <class 'float'>\n",
      "-11.2 <class 'float'>\n"
     ]
    }
   ],
   "source": [
    "# 分别显示对应数据和数据类型\n",
    "for i in [10, 1028, -104, 12.3, -11.2]:\n",
    "    print(i, type(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12000000000.0"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1.2e10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 布尔类型也是python自带的数据类型，只有True和False两类，注意首字母是大写的 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**python里面有一个特殊的字符，None，代表是空值**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**此外也有字符串类型，字符串类型需要使用英文单引号，或着双引号括起来，比如\"adb\", '你好'。如果字符串里面包含单引号，一种方法是通过转意字符进行表示，另外一种是通过外层使用双引号，需要注意的是这些都必须再一行，不能跨行。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"I'm tired\""
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"I'm tired\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"I'm tired\""
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"I\\'m tired\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**python里面也会常常看到成对的三个成对的双引号或者单引号，他们的好处是字符串可以跨行了**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'\\nselect\\nt1.*, t2.stock_price\\nfrom company t1, stock t2\\nwhere t1.name = t2.name\\n'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"\n",
    "select\n",
    "t1.*, t2.stock_price\n",
    "from company t1, stock t2\n",
    "where t1.name = t2.name\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**数字转字符串可以使用str函数，而只包含数字的字符串，可以通过int和float来转换成整数和浮点数**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1002'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(1002)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "123"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(123.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2344.23"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float('2344.23')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**常常我们需要讲字符串里面按照需求进行填充内容，可以使用.format()函数进行。字符串中的大括号'{}'代表要替换的内容，多个括号可以依次用多个内容替换**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1 + 1 = 2'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"1 + 1 = {}\".format(1+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好小明，今天是星期二\n"
     ]
    }
   ],
   "source": [
    "string = \"你好{}，今天是{}\".format('小明', '星期二')\n",
    "print(string)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 变量介绍\n",
    "**python里面任意的以数字和字母，以及下划线组成的符号（第一个不能是数字），都可以作为变量进行数据的表示，比如abc，a23，h_aad_22等等，而对变量可以通过等号进行赋值。变量不需要提前申明和定义，直接赋值后就能使用**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = 10\n",
    "b = 23.3\n",
    "abc = 'hola'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**python里面所有的变量都只是一个类似于C或C++语言的指针的东西，它并不储存具体的数据，而只是指向所赋予的数据的位置。所以在python的程序里面，你可以看到同一个变量一会儿被赋予一种类型的数据类型，一会儿又被赋予另外一种类型的数据**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "a123 = 1202\n",
    "print(a)\n",
    "a123 = 'hello'\n",
    "print(a123)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**print是python里面的输出函数，会讲结果直接展示出来，而help函数也是常用的函数，任何不清楚的命令，都可用help进行查看和帮助**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "multiple line\n",
      "can be put here\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print('''\n",
    "multiple line\n",
    "can be put here\n",
    "''')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function dir in module builtins:\n",
      "\n",
      "dir(...)\n",
      "    dir([object]) -> list of strings\n",
      "    \n",
      "    If called without an argument, return the names in the current scope.\n",
      "    Else, return an alphabetized list of names comprising (some of) the attributes\n",
      "    of the given object, and of attributes reachable from it.\n",
      "    If the object supplies a method named __dir__, it will be used; otherwise\n",
      "    the default dir() logic is used and returns:\n",
      "      for a module object: the module's attributes.\n",
      "      for a class object:  its attributes, and recursively the attributes\n",
      "        of its bases.\n",
      "      for any other object: its attributes, its class's attributes, and\n",
      "        recursively the attributes of its class's base classes.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数学运算符号\n",
    "**python和其它编程语言一样，支持加+，减-，乘*，除/， 次方 $**$ ，取余数 %，取商的整数部分 //**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.5\n",
      "-100\n",
      "20\n",
      "0.5\n",
      "1024\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "print(2 + 3.5)\n",
    "print(2 - 102)\n",
    "print(5 * 4)\n",
    "print(5 / 10)\n",
    "print(2**10)\n",
    "print(10 % 3)\n",
    "print(10 // 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**任何计算的结果的可以复制给想要的变量**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000\n"
     ]
    }
   ],
   "source": [
    "a = 10 **3\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**上面所有的运算符号都支持和等号=合并的运算，比如讲一个变脸加一然后赋值给这个变量**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a=1\n",
      "a=2\n",
      "a=3\n"
     ]
    }
   ],
   "source": [
    "a = 1\n",
    "print('a={}'.format(a))\n",
    "a = a + 1\n",
    "print('a={}'.format(a))\n",
    "a += 1\n",
    "print('a={}'.format(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**运算可以通过()进行改变，和数学运算符号是一样的**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "92\n"
     ]
    }
   ],
   "source": [
    "a = 12\n",
    "b = 34\n",
    "c = 2\n",
    "d = (a + b) * c\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python注释\n",
    "**python里面使用#来表示注释，任何以#开始到一行结束，都将会被python作为注释，而不会当作程序来进行编译**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "# a = 12\n",
    "# b = 10\n",
    "# c = a + b\n",
    "a = 1\n",
    "b = 2\n",
    "print(a + b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 逻辑运算符\n",
    "**<, >, =, != , ~ is 这些运算符都会返回布尔类型的数据**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 > 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 != 22"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "a = None\n",
    "print(a is None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### 程序运行流的控制\n",
    "\n",
    "**python里面的if语句和其它语句都是一样的，只是在格式上有一些区别**\n",
    "\n",
    "* 首先 if 语句直接接条件判断，并用冒号结尾\n",
    "* 其次 if 条件成立下运行的内容都需要缩进一个Tab的距离\n",
    "* if 可以和else进行配对，也可以和elif进行配对，前者执行所有前面没有匹配成功的情况，后者可以继续判断其它情况。和if一样，每一行的结尾都需要用冒号进行结束。\n",
    "* 对于复合的判断条件，可以使用and，or进行组合，如果逻辑过于复杂，最好用括号进行清晰的表示\n",
    "\n",
    "  if 判断条件1:\n",
    "      ...\n",
    "  elif 判断条件2:\n",
    "      ...\n",
    "  elif 判断条件3:\n",
    "      ...\n",
    "  else:\n",
    "      ...\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Go back to work\n"
     ]
    }
   ],
   "source": [
    "today = 'Monday'\n",
    "\n",
    "if today == 'Tuesday':\n",
    "    print('Four days to weekend')\n",
    "elif today == 'Sunday' or today == 'Saturday':\n",
    "    print('Have a nice weekend!')\n",
    "elif today == 'Monday':\n",
    "    print('Go back to work')\n",
    "else:\n",
    "    print('Hmm relax')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**上面的if else语句是多行的模式，python也支持写在一行的方式，如下面的例子**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "资金充足\n"
     ]
    }
   ],
   "source": [
    "money = 120\n",
    "x = '资金充足' if money > 100 else '余额不足'\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python循环的实现\n",
    "\n",
    "**和其它语言一样，for loop和while loop是python实现循环方法。for循环一般是遍历指定数量的循环方法，通常for循环是知道需要循环的次数的。而while loop是满足条件时才进行虚幻，通常的情况时我们并不一定知道循环的次数。**\n",
    "\n",
    "* 循环条件需要使用分号表示条件的结束\n",
    "* 循环的内容都需要向内缩进一个tab\n",
    "* 循环可以嵌套循环，但是注意每一次循环的运行内容都需要对应的缩进一个tab\n",
    "* 循环里面可以使用 *break* 来终止当前循环（只有*break*关联的一层循环会终止，其它循环不受影响）\n",
    "* 循环里面也可以使用*continue*来继续当前循环，同样也只有*continue*关联的循环会受到影响\n",
    "\n",
    "    for *xx* in *xxx*:\n",
    "        inner_for_loop\n",
    "        \n",
    "        \n",
    "    while 判定条件:\n",
    "        while_loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "求和: 0,2,4,6,8,\n",
      "计算结果为: 20\n"
     ]
    }
   ],
   "source": [
    "# range是用于生成序列的函数\n",
    "# range(0, 10, 2) 表示生成从0开始，步长为2的，并且不超过10的序列\n",
    "\n",
    "total = 0\n",
    "print('求和: ', end='')\n",
    "for x in range(0, 10, 2):\n",
    "    print(x, end=',')\n",
    "    total += x\n",
    "# 用于换行\n",
    "print()\n",
    "print('计算结果为: {}'.format(total))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1x1= 1| \n",
      "2x1= 2| 2x2= 4| \n",
      "3x1= 3| 3x2= 6| 3x3= 9| \n",
      "4x1= 4| 4x2= 8| 4x3=12| 4x4=16| \n",
      "5x1= 5| 5x2=10| 5x3=15| 5x4=20| 5x5=25| \n",
      "6x1= 6| 6x2=12| 6x3=18| 6x4=24| 6x5=30| 6x6=36| \n",
      "7x1= 7| 7x2=14| 7x3=21| 7x4=28| 7x5=35| 7x6=42| 7x7=49| \n",
      "8x1= 8| 8x2=16| 8x3=24| 8x4=32| 8x5=40| 8x6=48| 8x7=56| 8x8=64| \n",
      "9x1= 9| 9x2=18| 9x3=27| 9x4=36| 9x5=45| 9x6=54| 9x7=63| 9x8=72| 9x9=81| \n"
     ]
    }
   ],
   "source": [
    "# 该例子会输出乘法表\n",
    "# range(1，10)表示生成1到10（不包括），步长为1的序列\n",
    "for i in range(1, 10):\n",
    "    for j in range(1, 10):\n",
    "        if j > i:\n",
    "            # 当j大于i时，跳出j的循环，然后继续运行j的循环后面的内容\n",
    "            break\n",
    "        # format 里面可以设置自己的格式，可以参考\n",
    "        # http://www.runoob.com/python/att-string-format.html\n",
    "        print('{:1d}x{:1d}={:2d}|'.format(i, j, i*j), end=' ')\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100以内所有偶数的和为2450\n"
     ]
    }
   ],
   "source": [
    "# 计算100以内偶数的和\n",
    "# range(101)表示生成0到101的整数数（不包括101）\n",
    "total = 0\n",
    "for i in range(100):\n",
    "    # 不为偶数时，继续循环而不进行求和\n",
    "    if i % 2 != 0:\n",
    "        continue\n",
    "    total += i\n",
    "print('100以内所有偶数的和为{}'.format(total))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**while 循环的话通常来说我们并不知道其最终会运行多少次循环**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "计算求和: \n",
      "2,9,7,6,9,\n",
      "求和结果为: 33\n"
     ]
    }
   ],
   "source": [
    "# 这里我们引入random函数，后面会讲到怎么通过import来引入包\n",
    "from random import randint\n",
    "# help(randint)\n",
    "# randint(0，9)会生成[0,9]之间的所有的整数\n",
    "total = 0\n",
    "print('计算求和: ')\n",
    "\n",
    "# 当综合症小于25时继续求和\n",
    "while total < 25:\n",
    "    num = randint(0,9)\n",
    "    print(num, end=',')\n",
    "    total += num\n",
    "print()\n",
    "print('求和结果为: {}'.format(total))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       *\n",
      "      ***\n",
      "     *****\n",
      "    *******\n",
      "   *********\n",
      "  ***********\n",
      " *************\n"
     ]
    }
   ],
   "source": [
    "# 树的高度\n",
    "height = 7\n",
    "row = 0\n",
    "while row < height:\n",
    "    count = 0\n",
    "    while count < height - row:\n",
    "        print(end=' ')\n",
    "        count += 1\n",
    "    count = 0\n",
    "    while count < 2*row + 1:\n",
    "        print(end='*')\n",
    "        count += 1\n",
    "    print()\n",
    "    row += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python中引用其它包\n",
    "\n",
    "**python 通过import来进行包的调用，常见的有下面几种方式**\n",
    "\n",
    "1. import *package*\n",
    "2. import *package* as pkg\n",
    "3. from *pacakge* import *xxx*, *xxxx*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2开方后的结果为1.414\n",
      "e=2.718\n"
     ]
    }
   ],
   "source": [
    "# 如果我们知道一个包的名字，可以直接使用import来导入，比如我们import math\n",
    "import math\n",
    "\n",
    "# 调用math里面的函数就可以通过math.xxx来进行\n",
    "# 比如求平方根\n",
    "print('2开方后的结果为{:.3f}'.format(math.sqrt(2)))\n",
    "# 比如计算指数\n",
    "print('e={:.3f}'.format(math.exp(1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**上面我们对于每一个函数都需要前面放上math来说明，稍微显得有点冗余，我们可以通过直接from math import sqrt，exp来引入我们需要的包。**\n",
    "* from math import * 可以引入所有的math下面的包，但是一般不推荐这张做，因为会引入很多你可能不需要的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2开方后的结果为1.414\n",
      "e=2.718\n"
     ]
    }
   ],
   "source": [
    "from math import sqrt, exp\n",
    "print('2开方后的结果为{:.3f}'.format(sqrt(2)))\n",
    "print('e={:.3f}'.format(exp(1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2开方后的结果为1.414\n",
      "e=2.718\n"
     ]
    }
   ],
   "source": [
    "# 也可以用自己定义的m代替math\n",
    "import math as m\n",
    "print('2开方后的结果为{:.3f}'.format(m.sqrt(2)))\n",
    "print('e={:.3f}'.format(m.exp(1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python中的函数\n",
    "\n",
    "**python中通过def来定义函数，和if语句一样，函数名要以冒号:结尾，并且函数的内容需要缩进一个tab。函数可以使用return来进行数据的返回，如果不使用return，那么默认的返回数据为None。调用函数就是直接定义好的函数名称加上括号并在括号中传入对应需要的参数。**\n",
    "\n",
    "    def *function_name*(var1, var2, *arg, **kw):\n",
    "        do_something_here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5的阶乘为120\n"
     ]
    }
   ],
   "source": [
    "# 定义一个计算n的阶乘的函数\n",
    "def factorial(n):\n",
    "    product = 1\n",
    "    for i in range(1, n+1):\n",
    "        product *= i\n",
    "    return product\n",
    "\n",
    "result = factorial(5)\n",
    "print('5的阶乘为{}'.format(result))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**函数的参数也可以赋予一些默认值，通过=号来实现，但是对于那些放在赋予了默认值以后的变量，都必须要赋予默认值了**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 + 1 + 3 = 14\n"
     ]
    }
   ],
   "source": [
    "# 错误的赋予默认值的方法\n",
    "#def f(a, b=1, c):\n",
    "#    return a + b + c\n",
    "\n",
    "# 正确的方法如下\n",
    "\n",
    "def f(a, b=1, c=2):\n",
    "    return a + b + c\n",
    "\n",
    "print(\"10 + 1 + 3 = {}\".format(f(10, c=3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**对于不定个数的变量，可以使用\\*arg, \\**kw 来进行表示**\n",
    "* \\*arg 代表位置变量\n",
    "* \\**kw 代表字典变量（后面会详细介绍字典类型数据结构）\n",
    "* arg和kw可以换成你想要的任何名称，启主要作用的是\\*和\\**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "位置变量依次为:1,3,5,\n",
      "字典变量分别为:a=1,b=12,"
     ]
    }
   ],
   "source": [
    "def f(*arg, **kw):\n",
    "    print('位置变量依次为:', end='')\n",
    "    for v in arg:\n",
    "        print(v, end=',')\n",
    "    print()\n",
    "    # 字典类型的\n",
    "    print('字典变量分别为:', end='')\n",
    "    for k in kw:\n",
    "        print('{}={}'.format(k, kw[k]), end=',')\n",
    "        \n",
    "f(1, 3, 5, a=1, b=12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 变量的作用域\n",
    "\n",
    "**python中，变量的作用域和c++等其它编程有一定区别，我们用一些例子来进行说明**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "for循环的变量可以在for循环结束后被访问: for_var = 1\n",
      "for循环的内的变量也可以在for循环结束后被访问: var_in_for = 102\n"
     ]
    }
   ],
   "source": [
    "for for_var in range(2):\n",
    "    var_in_for = 102\n",
    "    pass\n",
    "print(\"for循环的变量可以在for循环结束后被访问: for_var = {}\".format(for_var))\n",
    "print(\"for循环的内的变量也可以在for循环结束后被访问: var_in_for = {}\".format(var_in_for))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x可以被函数内部引用，所以x+a = 110\n"
     ]
    }
   ],
   "source": [
    "# 函数内部的x因为没有定义，所以python认为其为外部的变量，所以使用了x=10\n",
    "x = 10\n",
    "def f(a=100):\n",
    "    print(x+a)\n",
    "print(\"x可以被函数内部引用，所以x+a = \", end='')\n",
    "f()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内部的x因为有赋值操作，所以函数内部的x是一个局部变脸，并不会改变函数外部的x，所以外部x依然为10\n"
     ]
    }
   ],
   "source": [
    "# 函数内部的x因为有赋值操作，所以函数内部的x是一个局部变脸，并不会改变函数外部的x\n",
    "x = 10\n",
    "def f(a=100):\n",
    "    x = 12\n",
    "    x += a\n",
    "\n",
    "f()\n",
    "print(\"函数内部的x因为有赋值操作，所以函数内部的x是一个局部变脸，并不会改变函数外部的x，所以外部x依然为{}\".format(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内部改变了外部的x， x=110\n"
     ]
    }
   ],
   "source": [
    "# 如果想直接在函数中修改外部的变量，我们需要使用global关键词，下面的做法是错误的\n",
    "#x = 10\n",
    "#def f(a=100):\n",
    "#    x += a\n",
    "#f()\n",
    "\n",
    "x = 10\n",
    "def f(a=100):\n",
    "    global x\n",
    "    x += a\n",
    "f()\n",
    "print('函数内部改变了外部的x， x={}'.format(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Python的数据结构 list\n",
    "\n",
    "**list是python中会经常用到的数据结构，它有下面的一些特点**\n",
    "\n",
    "* 它类似于数组，但是它的每一个元素可以是不同类型的，可以这样理解这一点，它的元素其实一些列指向各种不同数据位置的指针的集合\n",
    "* 它的每一个元素可以改变\n",
    "* 数组是从0开始计数的\n",
    "* 可以使用[i]进行访问它的第i个元素\n",
    "* 也可以使用[i:i+k]来访问第i个到第i+k（不含）个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "定义一个简单的list\n",
      "first=[1, 2, 3, 4, 5]\n",
      "通过2来访问第2个元素\n",
      "first[2]=3\n",
      "通过[1:3]来访问1到2元素\n",
      "first[1:3]=[2, 3]\n",
      "通过len函数来获取数组的个数为5\n"
     ]
    }
   ],
   "source": [
    "print(\"定义一个简单的list\")\n",
    "first = [1,2,3,4,5]\n",
    "print('first={}'.format(first))\n",
    "print(\"通过2来访问第2个元素\")\n",
    "print('first[2]={}'.format(first[2]))\n",
    "print('通过[1:3]来访问1到2元素')\n",
    "print('first[1:3]={}'.format(first[1:3]))\n",
    "print('通过len函数来获取数组的个数为{}'.format(len(first)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 10, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "# 修改数组的元素\n",
    "first = [1,2,3,4,5]\n",
    "first[2] = 10\n",
    "print(first)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n",
      "10\n",
      "[1, 2]\n",
      "aa\n"
     ]
    }
   ],
   "source": [
    "# 不同类型的元素\n",
    "var_list = ['a', 10, [1,2], 'aa']\n",
    "for v in var_list:\n",
    "    print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2] + [3, 4, 5] = [1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "# 数组的加法运算（连接）\n",
    "a = [1,2]\n",
    "b = [3,4,5]\n",
    "print(\"{} + {} = {}\".format(a, b, a+b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alist[-1] = 5\n",
      "alist[-4] = 2\n"
     ]
    }
   ],
   "source": [
    "# 访问倒数的元素\n",
    "alist = [1,2,3,4,5]\n",
    "print(\"alist[-1] = {}\".format(alist[-1]))\n",
    "print(\"alist[-4] = {}\".format(alist[-4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**list的修改和比较要特别注意，只有完全理解透彻才能不犯错一些隐藏的错误**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a==b is True\n",
      "a is b is True\n",
      "[1, 10, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "# b的值也会随着a的修改而修改，因为他们同时指向同一个数据地址\n",
    "a = [1,2,3,4]\n",
    "b = a\n",
    "print(\"a==b is {}\".format(a==b))\n",
    "print(\"a is b is {}\".format(a is b))\n",
    "a[1] = 10\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a==b is True\n",
      "a is b is False\n",
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "# a和b虽然内容一样，但是指向的是不同的数据地址，所以修改a不会修改b\n",
    "a = [1,2,3,4,5]\n",
    "b = [1,2,3,4,5]\n",
    "print(\"a==b is {}\".format(a==b))\n",
    "print(\"a is b is {}\".format(a is b))\n",
    "a[1] = 10\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 is in [1, 2, 3, 4, 5]\n",
      "4 is not in [1, 2, 3, 5]\n"
     ]
    }
   ],
   "source": [
    "# 判断一个元素是否在list里面用in\n",
    "\n",
    "a = [1,2,3,4,5]\n",
    "if 2 in a:\n",
    "    print('2 is in {}'.format(a))\n",
    "else:\n",
    "    print('2 is not in {}'.format(a))\n",
    "    \n",
    "b = [1,2,3,5]\n",
    "if 4 not in b:\n",
    "    print('4 is not in {}'.format(b))\n",
    "else:\n",
    "    print('4 is in {}'.format(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python tuple数据结构\n",
    "\n",
    "**python的tuple的数据结构可以想象成和list一样，但是定义好后就不能修改内容了（注意：不能修改的是tuple中的指针，但是如果tuple的指针指向内容是可能可以修改的）。tuple有下面的一些特点**\n",
    "* tuple的内容不能修改\n",
    "* tuple也和list一样有同样的访问方法\n",
    "* tuple也可以用len来计算个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 3)\n",
      "(1, 3, 4, 5)\n"
     ]
    }
   ],
   "source": [
    "# 定义tuple的方法\n",
    "a = 1, 2, 3\n",
    "b = (1, 3, 4, 5)\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a is b is False\n",
      "a == b is True\n"
     ]
    }
   ],
   "source": [
    "# 和list一样，分别定义也是不同的内容\n",
    "a = (1,2,3)\n",
    "b = (1,2,3)\n",
    "print(\"a is b is {}\".format(a is b))\n",
    "print(\"a == b is {}\".format(a == b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 下面写法是错误的，会报错\n",
    "#a = (1,2,3)\n",
    "#a[0] = 10 # 不能修改a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a[1]=1\n",
      "a[1:3] = (1, 2)\n",
      "(0, 1, 2, 3) + (4, 5, 6, 7) = (0, 1, 2, 3, 4, 5, 6, 7)\n",
      "len(a) = 4\n"
     ]
    }
   ],
   "source": [
    "a = (0,1,2,3)\n",
    "b = (4,5,6,7)\n",
    "print('a[1]={}'.format(a[1]))\n",
    "print('a[1:3] = {}'.format(a[1:3]))\n",
    "print(\"{} + {} = {}\".format(a, b, a+b))\n",
    "print(\"len(a) = {}\".format(len(a)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, [3, 4])\n",
      "(1, 2, [10, 4])\n"
     ]
    }
   ],
   "source": [
    "# 虽然a是tuple类型，但是我们偷偷修改了a的内容，这种方法不推荐，使用时要自己清楚可能有的问题\n",
    "a = (1,2, [3,4])\n",
    "print(a)\n",
    "a[2][0]=10\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, 1)\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "# 函数返回的带逗号的其实也是tuple数据结构\n",
    "def f(a, b):\n",
    "    return b, a\n",
    "c = f(1,3)\n",
    "print(c)\n",
    "print(type(c))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a = 20\n",
      "b = 10\n"
     ]
    }
   ],
   "source": [
    "a = 10\n",
    "b = 20\n",
    "# 交换两个变量的数据\n",
    "a, b = b, a\n",
    "print(\"a = {}\".format(a))\n",
    "print(\"b = {}\".format(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 is in (1, 2, 3, 4, 5)\n",
      "4 is not in (1, 2, 3, 5)\n"
     ]
    }
   ],
   "source": [
    "# 判断一个元素是否在tuple里面同样用in\n",
    "a = (1,2,3,4,5)\n",
    "if 2 in a:\n",
    "    print('2 is in {}'.format(a))\n",
    "else:\n",
    "    print('2 is not in {}'.format(a))\n",
    "    \n",
    "b = (1,2,3,5)\n",
    "if 4 not in b:\n",
    "    print('4 is not in {}'.format(b))\n",
    "else:\n",
    "    print('4 is in {}'.format(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python 字典（dictionary）数据结构介绍\n",
    "dictionary也是很常用的数据结构，和前面提到的list类似，不同的是list是通过位置来访问数据，dictionary是通过一个自己定义的名字来访问，这样更便于记忆和表达特殊的意义\n",
    "* 通过dict或者{}来定义\n",
    "* 使用自己定义的key来访问（任何可以被hashable的object都可以作为key）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "依次访问每一个成员\n",
      "name=abc\n",
      "age=12\n",
      "gender=male\n",
      "\n",
      "直接遍历字典\n",
      "abc\n",
      "12\n",
      "male\n"
     ]
    }
   ],
   "source": [
    "contact = {\n",
    "    'name': 'abc',\n",
    "    'age': 12,\n",
    "    'gender': 'male'\n",
    "}\n",
    "print('依次访问每一个成员')\n",
    "print('name={}'.format(contact['name']))\n",
    "print('age={}'.format(contact['age']))\n",
    "print('gender={}'.format(contact['gender']))\n",
    "print()\n",
    "print(\"直接遍历字典\")\n",
    "for key in contact:\n",
    "    print(contact[key])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'abc', 'age': 22, 'gender': 'male'}\n",
      "{'name': 'abc', 'age': 22, 'gender': 'male', 'country': 'China'}\n"
     ]
    }
   ],
   "source": [
    "contact = dict({\n",
    "    'name': 'abc',\n",
    "    'age': 12,\n",
    "    'gender': 'male'\n",
    "})\n",
    "\n",
    "contact['age'] += 10\n",
    "print(contact)\n",
    "# 可以新添加其它内容\n",
    "contact['country'] = 'China'\n",
    "print(contact)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'abc', 'age': 12, 'gender': 'male'} 包含name字段\n",
      "{'name': 'abc', 'age': 12, 'gender': 'male'} 不包含country字段\n"
     ]
    }
   ],
   "source": [
    "# 字典的数据类型也是通过in来判断是否存在某个字段\n",
    "contact = {\n",
    "    'name': 'abc',\n",
    "    'age': 12,\n",
    "    'gender': 'male'\n",
    "}\n",
    "\n",
    "if 'name' in contact:\n",
    "    print('{} 包含name字段'.format(contact))\n",
    "else:\n",
    "    print('{} 不包含name字段'.format(contact))\n",
    "\n",
    "if 'country' in contact:\n",
    "    print('{} 包含country字段'.format(contact))\n",
    "else:\n",
    "    print('{} 不包含country字段'.format(contact))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python中的集合（set）数据结构\n",
    "\n",
    "集合的概念和数学中的集合是一样的，也就是同一个元素在一个集合之中只会出现一次。下面用一些例子来说明集合的类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set_a = {1, 2, 3, 4, 5}\n",
      "set_b = {'c', 'a', 'b'}\n"
     ]
    }
   ],
   "source": [
    "# 集合的定义\n",
    "set_a = {1,2,3,4, 5, 5}\n",
    "print('set_a = {}'.format(set_a))\n",
    "set_b = set(['a', 'b', 'c', 'a'])\n",
    "print('set_b = {}'.format(set_b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set_a = {1, 2, 3, 4}\n"
     ]
    }
   ],
   "source": [
    "# 集合中添加新的元素\n",
    "set_a = {1,2,3}\n",
    "set_a.add(4)\n",
    "set_a.add(2)\n",
    "print('set_a = {}'.format(set_a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set_a = {1, 2}\n"
     ]
    }
   ],
   "source": [
    "# 集合中删除元素\n",
    "set_a = {1,2,3}\n",
    "set_a.remove(3)\n",
    "print('set_a = {}'.format(set_a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set_c = {1, 2, 3, 4, 5}\n",
      "set_d = {2, 3}\n"
     ]
    }
   ],
   "source": [
    "# 两个集合的并集和交集\n",
    "set_a = {1,2,3}\n",
    "set_b = {2,3,4,5}\n",
    "set_c = set_a | set_b\n",
    "print('set_c = {}'.format(set_c))\n",
    "set_d = set_a & set_b\n",
    "print('set_d = {}'.format(set_d))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2在集合{1, 2, 3}中 -- True\n",
      "5在集合{1, 2, 3}中 -- False\n"
     ]
    }
   ],
   "source": [
    "# 判断一个元素是否在一个集合中\n",
    "set_a = {1,2,3}\n",
    "is_2_in_set_a = 2 in set_a\n",
    "is_5_in_set_a = 5 in set_a\n",
    "print('2在集合{}中 -- {}'.format(set_a, is_2_in_set_a))\n",
    "print('5在集合{}中 -- {}'.format(set_a, is_5_in_set_a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Python中的类--Class\n",
    "\n",
    "**面向对象编程是很重要的概念和思想，在c++，java，c#，python等一系列高级编程语言中都有类的概念。这里我们简单介绍一些常用的概念和思想，简单来说，类就是一个函数和变量的集合，他们单独形成一个功能模块，使用的人可以将其当成一个黑盒子而不用具体了解其中的功能模块。**\n",
    "\n",
    "**类的定义以class关键词开始**\n",
    "\n",
    "    class ClassName(object):\n",
    "        \n",
    "        # 初始化函数\n",
    "        def __ini__(self):\n",
    "            pass\n",
    "        \n",
    "        # 其它任意函数\n",
    "        def other_function(self):\n",
    "            pass\n",
    "\n",
    "\n",
    "**所有的类都是从object类继承而来，所以上面的括号中有一个object，在python3中，即使不写（object），也会默认的认为继承的是object类。类其实就像是一个模板，就像捏泥人一样，得先做一个模板，然后再通过模板批量制造泥人。**\n",
    "\n",
    "**下面我们通过定义一个记录(x,y)坐标的类，来讲解python类的实现和使用。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "||p1|| = 1.4142135623730951\n",
      "p1 + p2 = (3.00, 4.00)\n",
      "p1 - p2 = (-1.00, -2.00)\n",
      "p1和p2之间的距离为2.24\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "# 定义类\n",
    "class Point(object):\n",
    "    \n",
    "    # __init__不需要显示的调用，当生成类的实例时，会自动的调用该函数\n",
    "    def __init__(self, x, y):\n",
    "        # 赋值类的成员变量，必须使用self为关键词\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "    \n",
    "    # 定义计算L2范数的公式，不需要参数，直接基于自身的数据\n",
    "    def norm(self):\n",
    "        l2_norm = math.sqrt(self.x**2 + self.y**2)\n",
    "        return l2_norm\n",
    "    \n",
    "    # 定义classmethod,来支持类直接调用函数,用以计算两个节点的距离\n",
    "    @classmethod\n",
    "    def l2_distance(cls, point1, point2):\n",
    "        new_point = point1 - point2\n",
    "        return new_point.norm()\n",
    "        \n",
    "    \n",
    "    # 重载加法运算（等python熟练后再慢慢掌握）\n",
    "    def __add__(self, other):\n",
    "        new_x = self.x + other.x\n",
    "        new_y = self.y + other.y\n",
    "        return Point(new_x, new_y)\n",
    "    \n",
    "    # 重载减法运算（等python熟练后再慢慢掌握）\n",
    "    def __sub__(self, other):\n",
    "        new_x = self.x - other.x\n",
    "        new_y = self.y - other.y\n",
    "        return Point(new_x, new_y)\n",
    "    \n",
    "    # 支持将类更好的表示出来（等python熟练后再慢慢掌握）\n",
    "    def __repr__(self):\n",
    "        return \"({:.2f}, {:.2f})\".format(self.x, self.y)\n",
    "    \n",
    "\n",
    "# 通过Point类来定义和实例\n",
    "p1 = Point(1, 1)\n",
    "p2 = Point(2, 3)\n",
    "\n",
    "# 通过.norm()来调用类的函数，从而计算L2 norm\n",
    "print(\"||p1|| = {}\".format(p1.norm()))\n",
    "# 计算两个节点的加法和减法运算\n",
    "print(\"p1 + p2 = {}\".format(p1 + p2))\n",
    "print(\"p1 - p2 = {}\".format(p1 - p2))\n",
    "\n",
    "# 计算p1和p2之间的距离\n",
    "# 注意我们是直接通过Point来调用的\n",
    "dist = Point.l2_distance(p1, p2)\n",
    "print('p1和p2之间的距离为{:.2f}'.format(dist))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**基于Point类，需要认真体会下面的方法的区别和错误原因**\n",
    "\n",
    "**正确的调用**\n",
    "\n",
    "* p1.norm()\n",
    "* p1.l2_distance(p1, p2)\n",
    "* Point.l2_distance(p1, p2)\n",
    "\n",
    "**错误的调用**\n",
    "\n",
    "* Point.norm()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Python中一些其它杂项\n",
    "\n",
    "**前面我们提到的字符串，也是字符串类的实例，所以它也有一系列的方法。比如：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ABCDE\n",
      "Abcde\n",
      "其它字符串支持的所有方法\n",
      "['capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']\n"
     ]
    }
   ],
   "source": [
    "a = 'abcde'\n",
    "# 转换成大写字符\n",
    "print(a.upper())\n",
    "# 转换成首字母大写\n",
    "print(a.capitalize())\n",
    "print('其它字符串支持的所有方法')\n",
    "print([ x for x in dir(a) if not x.startswith('_')])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "**同样字典类型也是字典类的实例，所以也有一系列的方法，比如**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['name', 'age', 'gender'])\n",
      "其它字典类型支持的所有方法\n",
      "['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']\n"
     ]
    }
   ],
   "source": [
    "contact = {\n",
    "    'name': 'abc',\n",
    "    'age': 12,\n",
    "    'gender': 'male'\n",
    "}\n",
    "# 输出所有的key\n",
    "print(contact.keys())\n",
    "print('其它字典类型支持的所有方法')\n",
    "print([ x for x in dir(contact) if not x.startswith('_')])   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**同样list，tuple，set类型都有自己的一些列方法**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set支持的所有方法\n",
      "['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']\n",
      "\n",
      "list支持的所有方法\n",
      "['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']\n",
      "\n",
      "tuple支持的所有方法\n",
      "['count', 'index']\n"
     ]
    }
   ],
   "source": [
    "a = {1,2,3}\n",
    "b = [1,2,3]\n",
    "c = (1,2,3)\n",
    "\n",
    "print('set支持的所有方法')\n",
    "print([ x for x in dir(a) if not x.startswith('_')])\n",
    "print()\n",
    "print('list支持的所有方法')\n",
    "print([ x for x in dir(b) if not x.startswith('_')])\n",
    "print()\n",
    "print('tuple支持的所有方法')\n",
    "print([ x for x in dir(c) if not x.startswith('_')])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**for循环也可以写在一行，通常用于生成一些想要的数据结构**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16]\n"
     ]
    }
   ],
   "source": [
    "# 所有的数据进行平方\n",
    "a = [1,2,3,4]\n",
    "b = [x**2 for x in a]\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 0, 'c': 0}\n"
     ]
    }
   ],
   "source": [
    "# 生成字典类型\n",
    "keys = ['a', 'b', 'c']\n",
    "new_dict = {key: 0 for key in keys if key != 'b'}\n",
    "print(new_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**在循环时，我们有事希望能获取数据的位置，此时通常enumerate来进行**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第0个数据为10\n",
      "第1个数据为20\n",
      "第2个数据为30\n",
      "第3个数据为40\n"
     ]
    }
   ],
   "source": [
    "a = [10,20,30,40]\n",
    "for i, v in enumerate(a):\n",
    "    print('第{}个数据为{}'.format(i, v))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** python中的map和filter **\n",
    "\n",
    "* map的功能主要是将函数应用到序列的每一个元素上面\n",
    "* filter的功能主要是在序列上面筛选满足条件的元素\n",
    "\n",
    "注意：map和fitler返回的都是generator类型（该教程没有介绍）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49]\n",
      "------------------------------\n",
      "[2, 4, 6]\n"
     ]
    }
   ],
   "source": [
    "def square(x):\n",
    "    return x**2\n",
    "\n",
    "def get_even(x):\n",
    "    return x % 2 == 0\n",
    "\n",
    "a = [1,2,3,4,5,6,7]\n",
    "\n",
    "square_a = map(square, a)\n",
    "print(list(square_a))\n",
    "print('-'*30)\n",
    "even_a = filter(get_even, a)\n",
    "print(list(even_a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "** 当函数比较简单是，可以使用lambda函数, lambda函数会将最后的结果自动返回，所以不需要使用return关键字 **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 4, 9, 16, 25, 36, 49]"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对数组中的每一个元素进行平方\n",
    "a = [1,2,3,4,5,6,7]\n",
    "list(map(lambda x: x**2, a))"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
